package com.ejy.base.data.interceptor;

import com.ejy.commons.exception.ParamsValidateException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * @Description:参数效验拦截器 Author    Version		Date		Changes
 * zhuangjianfa 1.0  2018年2月1日 Created
 */
@Order(1000)
@Aspect
@Component
public class ValidateParameterAspectAdvice {

    private Logger logger = LoggerFactory.getLogger(ValidateParameterAspectAdvice.class);

    @Before("execution(*  com.ejy.*.*.manager.impl.*.*(..))")
    public void before(JoinPoint pjd) {
        Object[] args = pjd.getArgs();
        if (args.length > 0) {
            Object oneParam = args[0];
            String check = checkParam(oneParam);
            if (check != null) {
                logger.error("ParamsValidateException , class={}, method={}, msg={}", pjd.getTarget().getClass().getSimpleName(), pjd.getSignature().getName(), check);
                throw new ParamsValidateException(1000, check);
            }
        }
    }
    

    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    public static <T> String checkParam(final T obj, final Class<?>... group) {
        List<String> list = new ArrayList<>();
        Set<ConstraintViolation<T>> constraintViolations = null;
        if(null==group) {
            constraintViolations = validator.validate(obj);
        }else {
            constraintViolations = validator.validate(obj,group);
        }
        final StringBuilder strBuilder = new StringBuilder();
        if (!constraintViolations.isEmpty()) {
            for (final ConstraintViolation<T> cv : constraintViolations) {
                if(!list.contains(String.valueOf(cv.getPropertyPath()))){
                    list.add(String.valueOf(cv.getPropertyPath()));
                    strBuilder.append(cv.getMessage()).append(";");
                }
            }
            return strBuilder.toString();
        }
        return null;
    }

    public static <T> String checkParam(final T obj, final Class<?> group) {
        List<String> list = new ArrayList<>();
        final Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj, group);
        final StringBuilder strBuilder = new StringBuilder();
        if (!constraintViolations.isEmpty()) {
            for (final ConstraintViolation<T> cv : constraintViolations) {
                if(!list.contains(String.valueOf(cv.getPropertyPath()))){
                    list.add(String.valueOf(cv.getPropertyPath()));
                    strBuilder.append(cv.getMessage()).append(";");
                }
            }
            return strBuilder.toString();
        }
        return null;
    }

    public static <T> String checkParam(final T obj, final Class<?> group, final String... args) {
        final StringBuilder strBuilder = new StringBuilder("");
        if (args != null) {
            for (final String param : args) {
                final Set<ConstraintViolation<T>> constraintViolations = validator.validateProperty(obj, param, group);
                if (!constraintViolations.isEmpty()) {
                    for (final ConstraintViolation<T> cv : constraintViolations) {
                        strBuilder.append(cv.getMessage()).append(";");
                    }
                }
            }
        }
        return strBuilder.toString().equals("") ? null : strBuilder.toString();
    }
}
